package cn.itcast.netty.c2;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;

import java.net.InetSocketAddress;

public class HelloClient {
    public static void main(String[] args) throws InterruptedException {
        // 1. 启动类
        new Bootstrap()
            // 2. 添加 EventLoop  其实这个我们客户端可以不用但是这里现在先统一
            .group(new NioEventLoopGroup())
            // 3. 选择客户端 channel 实现
            .channel(NioSocketChannel.class)
            // 4. 添加处理器
            .handler(new ChannelInitializer<NioSocketChannel>() {
                @Override // 在与服务器端连接建立后被调用
                protected void initChannel(NioSocketChannel ch) throws Exception {
                    //pipeline翻译过来就是流水线的意思 其实这里面就是一个责任链模式
                    //一个处理器处理完就交给下一个处理器去处理，直到所有处理器都处理完
                    //handler可以对数据或者啥的进行处理 处理器分为inbound(入站) 和 outbound(出站)
                    //数据输入时由inbound(入站)处理器来处理 数据输出就由outbound(出站)处理器来处理
                    //这里是个编码的handler 因为服务端是把字节转换成字符串读取，所以我们这边就得把要发的数据转换成字节然后发送
                    ch.pipeline().addLast(new StringEncoder());
                }
            })
            // 5. 连接到服务器 这是异步执行的  它会返回channelFuture的对象 只要是跟future有关的一般都会跟异步有关
            .connect(new InetSocketAddress("localhost", 8080))
            .sync() // 这是个阻塞方法，只有在连接建立完成后才会往下运行  因为connet方法是异步的不阻塞可能就连接还没建立完成就发数据肯定不行的
            .channel() //拿到channel对象 这里的channel对象自然就是服务器与客户端之间的channel对象了
            // 6. 向服务器发送数据 因为添加了处理器了 所以这里我们写的虽然是字符串但是在传输的时候会被处理成字节然后发送
            .writeAndFlush("hello, world");  //写入并且刷新 write()即只是放入缓冲区
    }
}
